package com.ihome.android.util;

import java.util.List;
import java.util.concurrent.CountDownLatch;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.text.TextUtils;

import com.ihome.android.analytic.JsonAnalytic;
import com.ihome.android.common.ConfigUtil;
import com.ihome.android.http.HttpActions;
import com.ihome.android.market2.info.CertificateInfo;
import com.ihome.android.util.exception.ITVException;
import com.ihome.android.util.log.LogUtil;


public class Confirmation {
	private static final String	TAG	= Confirmation.class.getSimpleName();
	private static String appSignInfo = null;
	private static CertificateInfo info = null;
	/**
	 * get packageinfo by pName has installed app
	 * 
	 * @param ctx
	 *            Context
	 * @param pName
	 * @return PackageInfo if not find return null
	 */
	public static PackageInfo getPackageInfoByAppName(Context ctx, String pName) {
		PackageInfo pInfo = null;
		if (pName != null) {
			PackageManager pm = ctx.getPackageManager();
			try {
				pInfo = pm.getPackageInfo(pName, PackageManager.GET_SIGNATURES);
			} catch (NameNotFoundException e) {
				e.printStackTrace();
			}
		}
		return pInfo;
	}

	/**
	 * get process name from pid
	 * 
	 * @param context
	 * @param pid
	 * @return process name
	 */
	public static String getProcessNameByPID(Context context, int pid) {
		String pkgName = null;
		ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

		for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
			if (processInfo.pid == pid) {
				pkgName = processInfo.processName;
				String[] pkgNameList = processInfo.pkgList;
				LogUtil.d(TAG, "进程id为" + pid + " 运行的应用程序共有  :  " + pkgNameList.length);
				PackageManager pm = context.getPackageManager();
				for (int i = 0; i < pkgNameList.length; i++) {
					ApplicationInfo appInfo;
					try {
						// 0代表没有任何标记; PackageManager.PERMISSION_GRANTED
						appInfo = pm.getApplicationInfo(pkgNameList[i], 0);
						pkgName = appInfo.packageName;
						
						if(!pkgName.contains(":")){
							break;
						}
					} catch (NameNotFoundException e) {
						e.printStackTrace();
					} 
				}
				break;
			}
		}
		return pkgName;
	}
	
	public static String getAppNameByPkgName(Context context, String pkgName){
		String appName = null;
		PackageManager manager = context.getPackageManager();
		Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
		mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
		final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
		
		if (apps != null) {
			final int count = apps.size();
			for (int i = 0; i < count; i++) {
				ResolveInfo info = apps.get(i);
				if(info.activityInfo.applicationInfo.packageName.equals(pkgName)){
					return info.loadLabel(manager).toString();
				}
			}
		}
		return appName;
	}

	/**
	 * get package information by process name
	 * 
	 * @param context
	 * @param processName
	 * @return package information
	 */
	public static PackageInfo getPackageInfoByProcessName(Context context, String processName) {
		PackageManager pm = context.getPackageManager();
		List<PackageInfo> packages = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
		for (int i = 0; i < packages.size(); i++) {
			PackageInfo packageInfo = packages.get(i);
			if (packageInfo.applicationInfo.processName.equals(processName)) {
				return packageInfo;
			}
		}
		return null;
	}

	public static boolean checkAPKSignature() {
		return false;
	}

	/**
	 * check the application is valid
	 * 
	 * @param pkinfo
	 * @return true, the application is valid false, the application is invalid
	 */
	public static CertificateInfo checkAPKSignature(final Context context, final PackageInfo pkinfo){
//		boolean ret = false;

		if (pkinfo == null || pkinfo.signatures == null || pkinfo.signatures.length == 0)
			return null;

		if (!ConfigUtil.appSignList.containsKey(pkinfo.packageName)) {
//			synchronized (ConfigUtil.ConfirmationSynObj) {
//				new Thread(new Runnable() {
//					
//					@Override
//					public void run() {
//						synchronized (ConfigUtil.ConfirmationSynObj) {
//						appSignInfo = getAPKSignature(context, pkinfo.packageName);
//						ConfigUtil.ConfirmationSynObj.notify();
//						}
//					}
//				}).start();
//				try {
//					ConfigUtil.ConfirmationSynObj.wait();
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
//			}
//			final Semaphore semaphore = new Semaphore(0);
//			semaphore.release();
//			semaphore.acquire();
			final CountDownLatch latch = new CountDownLatch(1);
			new Thread(new Runnable() {

				@Override
				public void run() {
					try {
						String result = new HttpActions(context).getAPKCertificate(pkinfo.packageName);
						LogUtil.v(TAG, "getAPKCertificate result-->" + result);
						info = JsonAnalytic.getInstance().analyseCertificateResult(result);
						if(info != null){
							LogUtil.d(TAG, "CertificateInfo = " + info.toString());
						}
					} catch (ITVException e) {
						e.printStackTrace();
					}
					
					latch.countDown();
				}
			}).start();
			try {
		        latch.await();
		    } catch (InterruptedException e) {
		        e.printStackTrace();
		    }
			
			if (info == null || TextUtils.isEmpty(info.getCertificate())) {
				return null;
			}
			ConfigUtil.appSignList.put(pkinfo.packageName, info.getCertificate());
		}
			
		appSignInfo = ConfigUtil.appSignList.get(pkinfo.packageName);
		if (pkinfo.signatures[0] != null && pkinfo.signatures[0].toCharsString().equals(appSignInfo)) {
			info.setIslegal(true);
		}
		else {
			info.setIslegal(false);
		}
		
		if(info != null){
			LogUtil.d(TAG, "checkAPKSignature APP = " + pkinfo.packageName + "; Is legal = " + info.islegal());
		}

		return info;
	}

	/**
	 * get application Signature from web
	 * 
	 * @param packagename
	 * @return AppSignInfo
	 */

	public static CertificateInfo getAPKSignature(Context context, String packagename) {
		if (packagename == null)
			return null;
		CertificateInfo info = null;
		try {
			String result = new HttpActions(context).getAPKCertificate(packagename);
			LogUtil.v(TAG, "getAPKSignature result-->" + result);
			info = JsonAnalytic.getInstance().analyseCertificateResult(result);
			if(info != null){
				LogUtil.d(TAG, "CertificateInfo = " + info.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		return info;
	}

	public static String getSignInfo(Context context, String packageName) {
		String signatrue;
		try {
			PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName,
					PackageManager.GET_SIGNATURES);
			Signature[] signs = packageInfo.signatures;
			Signature sign = signs[0];
			signatrue = sign.toCharsString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		LogUtil.i(TAG, "appSignInfo1 sb-->" + signatrue);
		return signatrue;
	}
	
	/**
	 * 
	 * get App VersionName by package Name
	 * 
	 * @param ctx
	 * @param pName
	 * @return
	 */
	public static String getVersion(Context ctx, String pName) {
		String version = "";
		try {
			PackageInfo packageInfo = getPackageInfoByAppName(ctx, pName);
			version = packageInfo.versionName;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return version;
	}
}
